#include "fxcc/imgui/Editor.h"
#include "fxcc/core/Dir.h"

using namespace fxcc::imgui;

template<>
bool Editor::Drag<float>(const std::string& label, float& v)
{
    return ImGui::DragFloat(label.c_str(), &v);
};


template<>
bool Editor::Input<float>(const std::string& label, float& v)
{
    return ImGui::InputFloat(label.c_str(), &v);
};

template<>
bool Editor::Input<int>(const std::string& label, int& v)
{
    return ImGui::InputInt(label.c_str(), &v);
};


bool Editor::InputMultiString(const std::string &label, std::string &value, int row)
{
    ImGui::PushID(&value);
    ImVector<char> my_str;
    for (auto ch : value)
    {
        my_str.push_back(ch);
    }

    my_str.push_back(0);

    bool res = InputMultiString(label, my_str, row);

    value.clear();
    for (auto r : my_str)
    {
        value.push_back(r);
    }
    value = value.substr(0, value.length() - 1);

    ImGui::PopID();
    return res;
}

bool Editor::InputMultiString(const std::string label, ImVector<char> &my_str, int row)
{

    if (my_str.empty())
    {
        my_str.push_back(0);
    }
    bool res = ImGui::InputTextMultiline(label.c_str(), my_str.begin(), (size_t)my_str.size(), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * row),
                                         ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void *)&my_str);


    return res;
}

bool Editor::InputString(const std::string label, std::string &value)
{
 
    ImVector<char> my_str;

    for (char ch : value)
    {
        my_str.push_back(ch);
    }

    my_str.push_back(0);

    bool res = ImGui::InputText(label.c_str(), my_str.begin(), (size_t)my_str.size(),
                                ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void *)&my_str);


    value.clear();
    for (const char &rch : my_str)
    {
        value.push_back(rch);
    }

    {

        if (ImGui::BeginDragDropTarget()) {
            if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("File")) {
                using T = fxcc::File;
                const T receivedData = *(const T*)payload->Data;
                value = receivedData.m_RelativePath;
            }
            ImGui::EndDragDropTarget();
        }
    }
    // value = value.substr(0, value.length() - 1);
    value = value.c_str();
    return res;
};

template <>
bool Editor::Edit<float>(const std::string &label, float &inst)
{
    bool res = ImGui::InputFloat(label.c_str(), &inst);
    return res;
}

template <>
bool Editor::Edit<double>(const std::string &label, double &inst)
{
    bool res = ImGui::InputFloat(label.c_str(), (float*)&inst);
    return res;
}

template <>
bool Editor::PathEdit<std::string>(const std::string& label, std::string& inst)
{
    bool res{ 0 };
    res |= InputString(label, inst);
    bool openEdit = ImGui::Button("Edit");
    res |= openEdit;
   
    if (openEdit)
    {
        sysx::System::OpenTextFile(inst);
    }
    return res;
}

template <>
bool Editor::Edit<std::string>(const std::string &label, std::string &inst)
{
    bool res = InputString(label, inst);
    return res;
}

template <>
bool Editor::Edit<int>(const std::string &label, int &inst)
{
    bool res = ImGui::InputInt(label.c_str(), &inst);
    return res;
}

template <>
bool Editor::Edit<unsigned int>(const std::string &label, unsigned &inst)
{
    bool res = ImGui::InputInt(label.c_str(), (int *)&inst);
    return res;
}

template <>
bool Editor::Edit<bool>(const std::string &label, bool &inst)
{
    bool res = ImGui::Checkbox(label.c_str(), &inst);
    return res;
}

bool Editor::Checkbox(const std::string &label, int &open, int index)
{
    bool bitMap = GetBit(open, index);
    bool res = ImGui::Checkbox(label.c_str(), &bitMap);
    SetBit(open, index, bitMap);

    return res;
}

bool Editor::TreeNode(const std::string& label, bool& open, ImGuiTreeNodeFlags flag)
{
    std::string label2 = label;
    if (label2.empty())
    {
        label2 = "[NULL]";
    }

    ImGui::SetNextItemOpen(open);
    open = ImGui::TreeNodeEx(label2.c_str(), flag);
    return open;
}

bool Editor::TreeNode(const std::string &label, int &open, int index, ImGuiTreeNodeFlags flag)
{
    std::string label2 = label;
    if (label2.empty())
    {
        label2 = "[NULL]";
    }
    bool bitMap = GetBit(open, index);
    if (bitMap)
        ImGui::SetNextItemOpen(bitMap);
    bool res = ImGui::TreeNodeEx(label2.c_str(), flag);

    SetBit(open, index, res);

    return res;
}


#include "sysx/System.h"

bool Editor::EditFilePath(const std::string& l, std::string& value)
{
    fs::path _p(value);
    if (ImGui::TreeNode(l.c_str()))
    {
        if (ImGui::Button("File"))
        {
            sysx::System::Filters filters;
            {
                sysx::System::Filter filter;
                filter.m_Name = "pro file(*.pro)";
                filter.m_Patterns.push_back("*.pro");
                filters.m_Filters.push_back(filter);
            }
            std::string path = sysx::System::OpenDialog("Save Path", filters, "");

            value = path;
        }
        ImGui::SameLine();
        ImGui::Text("%s", _p.filename().string().c_str());

        if (ImGui::IsItemHovered())
        {
            ImGui::SetTooltip("%s", _p.string().c_str());
        }
        ImGui::TreePop();
    }

    return false;
}